package jp.dodododo.aop.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javassist.CtBehavior;
import jp.dodododo.aop.Aspect;
import jp.dodododo.aop.Pointcut;
import jp.dodododo.aop.annotation.Enhance;
import jp.dodododo.aop.xml.XmlElement;

@Enhance(false)
public class AspectImpl implements Aspect, XmlElement {

	private List<Pointcut> pointcuts = new ArrayList<Pointcut>();

	private String targetClassPattern;

	private int lineNumber;

	public AspectImpl(String targetClassPattern, int lineNumber) {
		this.targetClassPattern = targetClassPattern;
		this.lineNumber = lineNumber;
	}

	public List<Pointcut> getPointcuts() {
		return pointcuts;
	}

	public void add(Pointcut pointcut) {
		pointcuts.add(pointcut);
	}

	public String[] getApplyInterceptorStatements(CtBehavior methodOrConstructor) {
		List<String> ret = new ArrayList<String>();
		for (Iterator<Pointcut> iter = pointcuts.iterator(); iter.hasNext();) {
			Pointcut pointcut = iter.next();
			if (pointcut.isApplied(methodOrConstructor) == true) {
				ret.add(pointcut.getInterceptorStatement());
			}
		}
		return ret.toArray(new String[ret.size()]);
	}

	public String getTargetClassPattern() {
		return targetClassPattern;
	}

	public int getLineNumber() {
		return lineNumber;
	}

	@Override
	public boolean equals(Object o) {
		try {
			AspectImpl target = (AspectImpl) o;
			return this.pointcuts.equals(target.pointcuts) && this.targetClassPattern.equals(target.targetClassPattern)
					&& this.lineNumber == target.lineNumber;
		} catch (ClassCastException e) {
			return false;
		}
	}

	@Override
	public int hashCode() {
		if (targetClassPattern == null) {
			return lineNumber;
		}
		return targetClassPattern.hashCode();
	}
}
